import { AuthService } from '@app/auth';
import { ConfigService } from '@app/config';
import { PrismaService } from '@app/prisma';
import { RedisService } from '@app/redis';
import { BadGatewayException, Inject, Injectable } from '@nestjs/common';
import { Prisma } from '@prisma/client';
import axios from 'axios';
import { v4 as getUuid } from 'uuid';

@Injectable()
export class UserService {
  @Inject(RedisService)
  private redisService: RedisService;
  @Inject(ConfigService)
  private configService: ConfigService;

  @Inject(AuthService)
  private authService: AuthService;

  @Inject(PrismaService)
  private prismaService: PrismaService;

  async getWxAuthToken() {
    let weapp_token = await this.redisService.get('xxx_weapp_token');
    if (!weapp_token) {
      const appid = this.configService.get('weapp.appid');
      const secret = this.configService.get('weapp.secret');

      const res = await axios.get(
        `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appid}&secret=${secret}`,
      );

      const { access_token, expires_in } = res.data;
      await this.redisService.set(
        'xxx_weapp_token',
        access_token,
        expires_in / 2,
      );
      weapp_token = access_token;
    }

    return weapp_token;
  }

  async getWxQrCode() {
    let weapp_token = await this.getWxAuthToken();
    const env_version = this.configService.get('weapp.env_version');
    const page = this.configService.get('weapp.login_path');
    const uuid = getUuid();
    const key = uuid.split('-').join('');
    const res = await axios.post(
      `https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=${weapp_token}`,
      {
        page,
        scene: key,
        check_path: true,
        env_version,
      },
      {
        responseType: 'arraybuffer',
      },
    );

    await this.redisService.set(
      `timeout_loginTag_xxx_${key}`,
      JSON.stringify({ status: 1 }),
      60,
    );
    return { file: res.data, key };
  }

  async checkTagKey(key: string) {
    const checkKey = await this.redisService.get(`timeout_loginTag_xxx_${key}`);
    const canUse = !!checkKey;
    if (!canUse) {
      throw new BadGatewayException('二维码已过期');
    }
    return checkKey;
  }

  async getWxOpenId(code: string) {
    try {
      const appid = this.configService.get('weapp.appid');
      const secret = this.configService.get('weapp.secret');
      const url = `https://api.weixin.qq.com/sns/jscode2session?appid=${appid}&secret=${secret}&js_code=${code}&grant_type=authorization_code`;
      const res = await axios.get(url);
      const data = res.data;
      return data.openid;
    } catch (error) {
      throw new BadGatewayException(error);
    }
  }
  async createUserByWxId(wxId: string) {
    try {
      const username = 'wx' + getUuid();
      const user = await this.prismaService.user.create({
        data: {
          wxId,
          username,
        },
      });
      return user;
    } catch (error) {
      throw new BadGatewayException(error);
    }
  }
  async getUserByWxId(wxId: string) {
    return await this.prismaService.user.findFirst({
      where: {
        wxId,
      },
    });
  }
  async login(loginMsg: { userId: string }, key: string) {
    const data = await this.authService.loginByJwt(loginMsg);
    await this.redisService.set(
      `xxx_token_${loginMsg.userId}`,
      data.access_token,
      data.expiresIn,
    );
    await this.redisService.set(
      `timeout_loginTag_xxx_${key}`,
      JSON.stringify({ status: 3, ...data }),
      20,
    );
    return data;
  }
}
